﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Management;
using System.Windows.Forms;

namespace Flickr2Frame
{
    public partial class DriveSelector : Form
    {
        BackgroundWorker driveQuery;
        string _SelectedDriveLetter = null;

        delegate void AddItemToComboBoxDelegate(string item, ref ComboBox combobox);
        delegate void ClearComboBoxItemsDelegate(ref ComboBox combobox);
        delegate int CountComboBoxItemsDelegate(ref ComboBox combobox);
        delegate void SelectComboBoxItemDelegate(int index, ref ComboBox combobox);

        public string SelectedDriveLetter
        {
            get
            {
                return _SelectedDriveLetter;
            }
        }

        struct Drive
        {
            public string letter;
            public string label;
        }

        public DriveSelector()
        {
            InitializeComponent();
            this.Load += new EventHandler(DriveSelector_Load);
            drivesComboBox.SelectedValueChanged += new EventHandler(drivesComboBox_SelectedValueChanged);
            okButton.Click += new EventHandler(okButton_Click);
        }

        void okButton_Click(object sender, EventArgs e)
        {
            _SelectedDriveLetter = drivesComboBox.SelectedItem.ToString().Split(Convert.ToChar(" "))[0];
        }

        void drivesComboBox_SelectedValueChanged(object sender, EventArgs e)
        {
            if (drivesComboBox.SelectedIndex != -1)
            {
                okButton.Enabled = true;
            }
            else
            {
                okButton.Enabled = false;
            }
        }

        void DriveSelector_Load(object sender, EventArgs e)
        {
            driveQuery = new BackgroundWorker();
            driveQuery.DoWork += new DoWorkEventHandler(driveQuery_DoWork);
            driveQuery.RunWorkerCompleted += new RunWorkerCompletedEventHandler(driveQuery_RunWorkerCompleted);
            driveQuery.RunWorkerAsync();
        }

        void driveQuery_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (CountComboBoxItems(ref drivesComboBox) == 0)
            {
                MessageBox.Show("No removable drives have been detected.\r\rPlease ensure you have powered on the frame, and plugged it into an available USB port.", "No Removable Drives", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.DialogResult = DialogResult.Cancel;
                this.Close();
            }

            if (CountComboBoxItems(ref drivesComboBox) == 1)
            {
                SelectComboBoxItem(0, ref drivesComboBox);
            }
        }

        void driveQuery_DoWork(object sender, DoWorkEventArgs e)
        {
            ClearComboBoxItems(ref drivesComboBox);

            foreach (Drive drive in GetDrives())
            {
                AddItemToComboBox(String.Format("{0} [{1}]", drive.letter, drive.label), ref drivesComboBox);
            }
        }

        void AddItemToComboBox(string item, ref ComboBox combobox)
        {
            if (InvokeRequired)
            {
                Invoke(new AddItemToComboBoxDelegate(AddItemToComboBox), new object[] { item, combobox });
            }
            else
            {
                combobox.Items.Add(item);
            }
        }

        void ClearComboBoxItems(ref ComboBox combobox)
        {
            if (InvokeRequired)
            {
                Invoke(new ClearComboBoxItemsDelegate(ClearComboBoxItems), new object[] { combobox });
            }
            else
            {
                combobox.Items.Clear();
            }
        }

        int CountComboBoxItems(ref ComboBox combobox)
        {
            if (InvokeRequired)
            {
                return Convert.ToInt32(Invoke(new CountComboBoxItemsDelegate(CountComboBoxItems), new object[] { combobox }));
            }
            else
            {
                return combobox.Items.Count;
            }
        }

        void SelectComboBoxItem(int index, ref ComboBox combobox)
        {
            if (InvokeRequired)
            {
                Invoke(new SelectComboBoxItemDelegate(SelectComboBoxItem), new object[] { index, combobox });
            }
            else
            {
                if ((index == -1) || (combobox.Items.Count > 0))
                {
                    combobox.SelectedIndex = index;
                }
            }
        }

        Drive[] GetDrives()
        {
            ArrayList drives = new ArrayList();
            ManagementObjectSearcher mos = new ManagementObjectSearcher(@"\\.\root\CIMV2", "SELECT DeviceID, VolumeName, Description FROM Win32_LogicalDisk WHERE DriveType='2' OR DriveType='3'");
            ManagementObjectCollection moc = mos.Get();

            if (moc.Count > 0)
            {
                foreach (ManagementObject mo in moc)
                {
                    //if (mo.Properties["DeviceID"].Value.ToString().ToUpper() != "A:")
                    //{
                        Drive drive = new Drive();
                        drive.letter = mo.Properties["DeviceID"].Value.ToString();
                        
                        if (mo.Properties["VolumeName"].Value != null)
                        {
                            drive.label = mo.Properties["VolumeName"].Value.ToString();
                        }
                        else
                        {
                            drive.label = mo.Properties["Description"].Value.ToString();
                        }

                        drives.Add(drive);
                    //}
                }
            }

            return drives.ToArray(typeof(Drive)) as Drive[];
        }
    }
}
